import json
from django.shortcuts import render
from django.http import HttpResponse,JsonResponse
from django.views.decorators.csrf import csrf_exempt



@csrf_exempt        # 免除csrf认证
def index(request):
    return HttpResponse('index')

def users(request):
    user_list = ['alex','oldboy']
    return HttpResponse(json.dumps(user_list))

from django.views import View
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt,name='dispatch')
class StudentView(View):
    def get(self,request,*args,**kwargs):
        return HttpResponse('GET')
    def post(self,request,*args,**kwargs):
        return HttpResponse('POST')
    def put(self,request,*args,**kwargs):
        return HttpResponse('PUT')
    def delete(self,request,*args,**kwargs):
        return HttpResponse('DELETE')


# #################################################

def get_order(request):
    return HttpResponse("")

def add_order(request):
    return HttpResponse("")

def del_order(request):
    return HttpResponse("")

def update_order(request):
    return HttpResponse("")

# #################################################

def order(request):
    if request.method == 'GET':
        return HttpResponse("获取订单")
    if request.method == 'POST':
        return HttpResponse("创建订单")
    if request.method == 'PUT':
        return HttpResponse("更新订单")
    if request.method == 'DELETE':
        return HttpResponse("删除订单")

# class OrderView(View):
#     def get(self,request,*args,**kwargs):
#
#         rec = {
#             'code':1000,
#             'msg':'xxx',
#         }
#         return HttpResponse(json.dumps(rec))
#
#     def post(self,request,*args,**kwargs):
#         return HttpResponse('创建订单')
#     def put(self,request,*args,**kwargs):
#         return HttpResponse('更新订单')
#     def delete(self,request,*args,**kwargs):
#         return HttpResponse('删除订单')

# ############ rest framework ##############
from django.views import View
from rest_framework.views import APIView
from rest_framework import exceptions
from rest_framework.request import Request

class MyAuthentication(object):
    def authenticate(self,request):
        token = request._request.GET.get('token')
        # 获取用户名和密码，去数据校验
        if not token:
            raise exceptions.AuthenticationFailed('用户认证失败')
        return ('alex',None)

    def authenticate_header(self,val):
        pass

class DogView(APIView):

    # authentication_classes = [MyAuthentication,]

    def get(self,request,*args,**kwargs):
        # self.dispatch
        print(request)
        print(request.user)
        rec = {
            'code':1000,
            'msg':'xxx',
        }
        return HttpResponse(json.dumps(rec))

    def post(self,request,*args,**kwargs):
        return HttpResponse('创建Dog')

    def put(self,request,*args,**kwargs):
        return HttpResponse('更新Dog')

    def delete(self,request,*args,**kwargs):
        return HttpResponse('删除Dog')


# ###########################################
from rest_framework.views import APIView
from . import models

ORDER_DICT = {
    1:{
        'name':'媳妇',
        'age':'18',
        'gender':'男',
        'content':'...'
    },
    2:{
        'name':'老狗',
        'age':'19',
        'gender':'男',
        'content':'...'
    },
}

def md5(user):
    import hashlib
    import time
    ctime = str(time.time())
    m = hashlib.md5(bytes(user,encoding='utf-8'))
    m.update(bytes(ctime,encoding='utf-8'))
    return m.hexdigest()


from .utils.permission import SVIPPermission,MyPermission1
from .utils.throttle import VisitThrottle
from rest_framework.viewsets import ModelViewSet

class AuthView(APIView):
    '''
    用于用户登陆认证
    '''
    authentication_classes = []
    permission_classes = []
    throttle_classes = [VisitThrottle,]

    def post(self,request,*args,**kwargs):
        # self.dispatch()
        # 1.去request中获取IP
        # 2.访问记录...

        ret = {'code':1000,'msg':None}
        try:
            user = request._request.POST.get('username')
            pwd = request._request.POST.get('password')
            obj = models.UserInfo.objects.filter(username=user,password=pwd).first()
            if not obj:
                ret['code'] = 1001
                ret['msg'] = "用户名或密码错误"
            # 为登陆用户创建token
            token = md5(user)
            # 存在就更新，不存在就创建
            models.UserToken.objects.update_or_create(user=obj, defaults={'token':token})
            ret['token'] = token

        except Exception as e:
            ret['code'] = 1002
            ret['msg'] = "请求异常"

        return JsonResponse(ret)

class OrderView(APIView):
    '''
    订单相关业务（只有SVIP用户有权限）
    '''
    # authentication_classes = [FirstAuthtication,Authtication,]
    # permission_classes = [SVIPPermission,]

    def get(self,request,*args,**kwargs):
        # request.user
        # request.auth

        ret = {'code':1000,'msg':None,'data':None}
        try:
            ret['data'] = ORDER_DICT
        except Exception as e:
            pass
        return JsonResponse(ret)

    def post(self,request,*args,**kwargs):
        return HttpResponse('创建Dog')

    def put(self,request,*args,**kwargs):
        return HttpResponse('更新Dog')

    def delete(self,request,*args,**kwargs):
        return HttpResponse('删除Dog')

# class UserInfoView(APIView):
#     '''
#     订单相关业务（普通用户、VIP）
#     '''
#     permission_classes = [MyPermission1,]
#     def get(self,request,*args,**kwargs):
#         print(request.user)
#         return HttpResponse('用户信息')


# ############ 版本 #############
from rest_framework.versioning import QueryParameterVersioning, URLPathVersioning
from django.urls import reverse

# class ParamVersion(object):
#     def determine_version(self, request, *args, **kwargs):
#         version = request.query_params.get('version')
#         print(version)
#         return version

class UsersView(APIView):
    # versioning_class = URLPathVersioning
    def get(self,request,*args,**kwargs):

        print(request._request)

        # version = request._request.GET.get('version')
        # print(version)
        # version = request.query_params.get('version')
        # print(version)
        # 获取版本
        print(request.version)
        # 获取处理版本的对象
        print(request.versioning_scheme)

        # 反向生成url(rest fromework)
        u1 = request.versioning_scheme.reverse(viewname='restful:uuu',request=request)
        print(u1)

        # 反向生成url
        u2 = reverse(viewname='restful:uuu',kwargs={'version':2})
        print(u2)

        return HttpResponse('用户列表')

class DjangoView(APIView):
    def post(self,request,*args,**kwargs):
        print(type(request._request))
        from django.core.handlers.wsgi import WSGIRequest
        return HttpResponse('POST和Body')

from rest_framework.request import Request
from rest_framework.parsers import JSONParser, FormParser

class ParseView(APIView):
    # parser_classes = [JSONParser,FormParser,]
    '''
    JSONParser: 表示只能解析 content-type:application/json 头
    FormParser: 表示只能解析 content-type:application/x-www-form-urlencoded 头
    '''
    def post(self,request,*args,**kwargs):
        """
        允许用户发送json格式数据
            a. content-type:application/json
            b. {'name':'alax','age':18}
        """
        '''
        1.获取用户的请求头
        2.获取用户的请求体
        3.根据用户请求头 和 parser_classes = [JSONParser,FormParser,] 中支持的请求头进行比较
        4.JSONParser对象去请求体
        5.request.data
        '''
        print(request.data)
        return HttpResponse('POST和Body')

# ######### 序列化 ###########
from . import models
from rest_framework import serializers

class RolesSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField()


class RolesView(APIView):
    def get(self,request,*args,**kwargs):

        # 方式一
        # roles = models.Role.objects.all().values('id','title')
        # roles = list(roles)
        # ret = json.dumps(roles,ensure_ascii=False)

        # 方式二：对于 [obj,obj,obj,]
        # roles = models.Role.objects.all()
        # ser = RolesSerializer(instance=roles,many=True)
        # ret = json.dumps(ser.data,ensure_ascii=False)

        roles = models.Role.objects.all().first()
        ser = RolesSerializer(instance=roles,many=False)
        # ser.data 已经是转换完成的 结果
        ret = json.dumps(ser.data,ensure_ascii=False)
        return HttpResponse(ret)

# class UserInfoSerializer(serializers.Serializer):
#     xxx = serializers.CharField(source="user_type")     # row.user_type
#     ooo = serializers.CharField(source="get_user_type_display")     # row.get_user_type_display()
#     username = serializers.CharField()
#     password = serializers.CharField()
#     gp = serializers.CharField(source="group.title")
#     # rls = serializers.CharField(source="roles.all")
#     rls = serializers.SerializerMethodField()     # 自定义显示
#     def get_rls(self,row):
#         role_obj_list = row.roles.all()
#         ret = []
#         for item in role_obj_list:
#             ret.append({'id':item.id,'title':item.title})
#         return ret

# class MyField(serializers.CharField):
#     def to_representation(self,value):
#         print(value)
#         return 'xxxxx'
#
# class UserInfoSerializer(serializers.ModelSerializer):
#     ooo = serializers.CharField(source="get_user_type_display")     # row.get_user_type_display()
#     rls = serializers.SerializerMethodField()     # 自定义显示
#     x1 = MyField(source='username')
#
#     class Meta:
#         model = models.UserInfo
#         # fields = "__all__"
#         fields = ['id','username','password','ooo','rls','group','x1']
#
#     def get_rls(self,row):
#         role_obj_list = row.roles.all()
#         ret = []
#         for item in role_obj_list:
#             ret.append({'id':item.id,'title':item.title})
#         return ret

class UserInfoSerializer(serializers.ModelSerializer):
    group = serializers.HyperlinkedIdentityField(view_name="restful:gp",lookup_field="group_id",lookup_url_kwarg="xxx")  # 返回url

    class Meta:
        model = models.UserInfo
        # fields = "__all__"
        fields = ['id','username','password','group','roles']
        depth = 0   # 0 ~ 10

class UserInfoView(APIView):
    def get(self,request,*args,**kwargs):

        users = models.UserInfo.objects.all()

        # 对象，Serializer类处理：self.to_representation
        # QuerySet, ListSerializer类处理：self.to_representation
        # 1.实例化，一般是将数据封装到对象：__new__,__init__
        """
        many=True,ListSerializer对象，接下来执行ListSerializer对象的构造方法
        many=False,接下来执行UserInfoSerializer对象的构造方法
        """
        ser = UserInfoSerializer(instance=users,many=True,context={'request':request})
        # print(ser.data)
        # 2. 调用对象的data属性
        # ListSerializer
        # UserInfoSerializer
        ret = json.dumps(ser.data,ensure_ascii=False)
        return HttpResponse(ret)

    # def post(self,request,*args,**kwargs):
    #     print(request.data)
    #
    #     return HttpResponse('提交数据')

class GroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserGroup
        fields = "__all__"

class GroupView(APIView):
    def get(self,request,*args,**kwargs):
        pk = kwargs.get('xxx')
        obj = models.UserGroup.objects.filter(pk=pk).first()
        print(obj)
        ser = GroupSerializer(instance=obj,many=False)
        ret = json.dumps(ser.data,ensure_ascii=False)
        return HttpResponse(ret)


# ################ 验证 #####################

class xxValidator(object):
    def __init__(self, base):
        self.base = str(base)

    def __call__(self, value):
        if not value.startswith(self.base): # startswith() 以什么开头
            message = '标题必须以 %s 为开头.' % self.base
            raise serializers.ValidationError(message)

    def set_context(self, serializer_field):
        """
        This hook is called by the serializer instance,
        prior to the validation call being made.
        """
        # 执行验证之前调用，serializer_fields是当前字段对象
        pass

class UserGroupSerializer(serializers.Serializer):
    title = serializers.CharField(error_messages={'required':'标题不能为空'},validators=[xxValidator('老男人')])

    def validate_title(self,value):
        from rest_framework import exceptions
        raise exceptions.ValidationError('看你不顺眼')
        # print(value,111111111)
        # return value

class UserGroupView(APIView):
    def post(self,request,*args,**kwargs):
        print(request.data)
        ser = UserGroupSerializer(data=request.data)
        if ser.is_valid():
            print(ser.validated_data['title'])
        else:
            print(ser.errors)

        return HttpResponse('提交数据')

# ####### 分页 ##########

from restful.utils.serializers.pager import PagerSerializers
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination

# class MyPageNumberPagination(PageNumberPagination):
#     page_size = 2   # 每页默认
#     page_size_query_param = 'size'  # 个数变量
#     max_page_size = 5       # 最大个数
#
#     page_query_param = 'page'

# class MyPageNumberPagination(LimitOffsetPagination):
#     default_limit = 2
#     limit_query_param = 'limit' # 个数
#     offset_query_param = 'offset'   # 位置
#     max_limit = 5

class MyPageNumberPagination(CursorPagination):
    cursor_query_param = 'cursor'
    page_size = 2
    ordering = 'id'
    page_size_query_param = None
    max_page_size = None

class Pager1View(APIView):
    def get(self,request,*args,**kwargs):
        # 获取所有数据
        roles = models.Role.objects.all()
        # 创建分页对象
        # pg = PageNumberPagination()
        pg = MyPageNumberPagination()
        # pg = LimitOffsetPagination()
        # pg = CursorPagination()

        # 在数据库中获取分页的数据
        pager_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
        # 对数据进行序列化
        ser = PagerSerializers(instance=pager_roles,many=True)

        # return Response(ser.data)
        return pg.get_paginated_response(ser.data)


# ####### 视图 ##########
'''
from restful.utils.serializers.pager import PagerSerializers
from rest_framework.generics import GenericAPIView
from rest_framework.viewsets import GenericViewSet

class ViewView(GenericAPIView):
    queryset = models.Role.objects.all()
    serializer_class = PagerSerializers
    pagination_class = PageNumberPagination

    def get(self,request,*args,**kwargs):
        # 获取数据
        roles = self.get_queryset()     # model.Role.objects.all()
        # [1,1000,]  [1,10] 分页
        pager_roles = self.paginate_queryset(roles)
        # 序列化
        ser = self.get_serializer(instance=pager_roles,many=True)
        return Response(ser.data)
'''

'''
from restful.utils.serializers.pager import PagerSerializers
from rest_framework.viewsets import GenericViewSet

class ViewView(GenericViewSet):
    queryset = models.Role.objects.all()
    serializer_class = PagerSerializers
    pagination_class = PageNumberPagination

    def list(self,request,*args,**kwargs):
        # 获取数据
        roles = self.get_queryset()     # model.Role.objects.all()
        # [1,1000,]  [1,10] 分页
        pager_roles = self.paginate_queryset(roles)
        # 序列化
        ser = self.get_serializer(instance=pager_roles,many=True)
        return Response(ser.data)
'''
from restful.utils.serializers.pager import PagerSerializers
from rest_framework.viewsets import GenericViewSet,ModelViewSet
from rest_framework.mixins import ListModelMixin,CreateModelMixin,DestroyModelMixin

class ViewView(ModelViewSet):
    queryset = models.Role.objects.all()
    serializer_class = PagerSerializers
    pagination_class = PageNumberPagination
    #
    # def list(self,request,*args,**kwargs):
    #     # 获取数据
    #     roles = self.get_queryset()     # model.Role.objects.all()
    #     # [1,1000,]  [1,10] 分页
    #     pager_roles = self.paginate_queryset(roles)
    #     # 序列化
    #     ser = self.get_serializer(instance=pager_roles,many=True)
    #     return Response(ser.data)


# ######### 渲染 ##########
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer,AdminRenderer,HTMLFormRenderer

class TestView(APIView):

    # renderer_classes = [JSONRenderer,BrowsableAPIRenderer]

    def get(self,request,*args,**kwargs):
        # 获取所有数据
        roles = models.Role.objects.all()

        # 创建分页对象
        # pg = PageNumberPagination()
        pg = MyPageNumberPagination()

        # 在数据库中获取分页的数据
        pager_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)

        # 对数据进行序列化
        ser = PagerSerializers(instance=pager_roles,many=True)

        return Response(ser.data)
        # return pg.get_paginated_response(ser.data)

